package fr.umlv.m2.jee.ldap.service.authentification;

import java.util.List;

import org.apache.log4j.Logger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.userdetails.ldap.LdapUserDetailsImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("userService")
public class DefaultUserService implements UserService, ApplicationContextAware {
    private static final Logger LOG = Logger.getLogger(DefaultUserService.class);
    private static final String ROLE_TEACHER = "ROLE_TEACHER";
    private static final String ROLE_STUDENT = "ROLE_STUDENT";

    private ApplicationContext applicationContext;

    @Override
    @Transactional(readOnly = true)
    public LdapSampleUserDetails getCurrentUserDetails() {
        SecurityContext securityContext = SecurityContextHolder.getContext();

        Object principal = securityContext.getAuthentication().getPrincipal();
        if (principal instanceof String) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("User is anonymous.");
            }
            return null;
        } else {
            LdapSampleUserDetails ldapSampleUserDetails = (LdapSampleUserDetails) this.applicationContext.getBean("ldapSampleUserDetails");
            if (ldapSampleUserDetails.getUsername() == null) {
                LOG.debug("User is not cached in session.");
                LdapUserDetailsImpl userDetails = (LdapUserDetailsImpl) securityContext.getAuthentication().getPrincipal();

                ldapSampleUserDetails.setDn(userDetails.getDn());
                ldapSampleUserDetails.setUsername(userDetails.getUsername());

                GrantedAuthority[] authorities = userDetails.getAuthorities();
                for (GrantedAuthority authority : authorities) {
                    if (ROLE_TEACHER.equals(authority.getAuthority())) {
                        ldapSampleUserDetails.setTeacher(true);
                    }
                    if (ROLE_STUDENT.equals(authority.getAuthority())) {
                        ldapSampleUserDetails.setStudent(true);
                    }
                }
            }
            return ldapSampleUserDetails;
        }
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}
